﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace DesignModeConsole.SolidPrinciple.single_responsibility_principle
{
    /// <summary>
    /// 正方形
    /// </summary>
    internal class Square
    {
        public Square(double length)
        {
            SideLength = length;
        }

        public double SideLength { get; init; }
    }

    /// <summary>
    /// 圆形
    /// </summary>
    internal class Circle
    {
        public Circle(double radius)
        {
            Radius = radius;
        }

        public double Radius { get; init; }
    }

    #region 错误设计

    /// <summary>
    /// 错误的设计  因为既计算的所有形状的面积之和，又处理了输出数据的格式
    /// </summary>
    internal class AreaCalculator
    {
        private List<object> _shapes;

        public AreaCalculator(List<object> shapes)
        {
            _shapes = shapes;
        }

        /// <summary>
        /// 计算所有形状的面积总和
        /// </summary>
        /// <returns></returns>
        public double Sum()
        {
            List<double> areas = new List<double>();

            foreach (var item in _shapes)
            {
                if (item is Square s)
                {
                    areas.Add(Math.Pow(s.SideLength, 2));
                }
                else if (item is Circle c)
                {
                    areas.Add(Math.PI * Math.Pow(c.Radius, 2));
                }
            }

            return areas.Sum();
        }

        public string Output()
        {
            return $"Sum of the areas of provided shapes: {Sum()}";
        }
    }

    #endregion

    #region 正确的设计

    /// <summary>
    /// 专门处理计算总和
    /// </summary>
    internal class AreaCalculator2
    {
        private List<object> _shapes;

        public AreaCalculator2(List<object> shapes)
        {
            _shapes = shapes;
        }

        /// <summary>
        /// 计算所有形状的面积总和
        /// </summary>
        /// <returns></returns>
        public double Sum()
        {
            List<double> areas = new List<double>();

            foreach (var item in _shapes)
            {
                if (item is Square s)
                {
                    areas.Add(Math.Pow(s.SideLength, 2));
                }
                else if (item is Circle c)
                {
                    areas.Add(Math.PI * Math.Pow(c.Radius, 2));
                }
            }

            return areas.Sum();
        }
    }

    /// <summary>
    /// 专门处理输出
    /// </summary>
    internal class SumCalculatorOutputter
    {
        protected AreaCalculator _calculator;

        public SumCalculatorOutputter(AreaCalculator calculator)
        {
            _calculator = calculator;
        }

        public string String()
        {
            return $"Sum of the areas of provided shapes: {_calculator.Sum()}";
        }

        public string JSON()
        {
            var data = new { Sum = _calculator.Sum() };
            return System.Text.Json.JsonSerializer.Serialize(data);
        }
    }

    #endregion
}